﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: Propietario			*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System.Collections.Generic;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using ESF.General;
using ESF.General.Entity;
using ESF.SSO.Core.Entities;
using ESF.SSO.Web.Tools.Modules;
using ESF.SSO.Web.Tools.Presenter;
using ESF.Web;
using ESF.Web.Pages;
using System;
using System.Diagnostics;

#endregion


namespace ESF.SSO.Web.Tools.ServerControls
{
	[AspNetHostingPermission(SecurityAction.Demand,
        Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand, 
        Level = AspNetHostingPermissionLevel.Minimal),
	ToolboxData ("<{0}:SignIn runat=\"server\"></{0}:SignIn>")]
	public class SignIn : BaseServerControl<SignInPresenter>, ISignInViewer, INamingContainer
	{
		#region Propiedades

		public string LinkTarget
		{
			set
			{
				ViewState["LinkTarget"] = value;
			}
			get
			{
				if (ViewState["LinkTarget"] == null)
				{
					return AuthenticationModule.LinkTarget;
				}

				return ViewState["LinkTarget"] as string;
			}
		}

		#endregion


		#region Delegados
		
		public delegate void SignedInEvent ();
		
		public event SignedInEvent SignedIn;
		
		#endregion
	
	
		#region Miembros
		
		private Button btnSignIn;
		private Button btnSignUp;

		private HyperLink lnkShow;

		private TextBox txtUserAlias;
		private TextBox txtUserPassword;
		
		private RequiredFieldValidator rfvTxtUserPassword;
		private RequiredFieldValidator rfvTxtUserAlias;

		private HyperLink lnkForgetPassword;
		
		private HiddenField hidTopQueryString;
		
		private string _OnSignInJS;
		
		#endregion
		
		
		#region Propiedades
		
		[Bindable(false),
		Category("Validation"),
		DefaultValue("SignIn"),
		Description("The Validation Group for this form"),
		Localizable(false)]
		public string ValidationGroup
		{
		    get
		    {
				if (ViewState["ValidationGroup"] == null)
				{
					return "SignIn";
				}
				
				return ViewState ["ValidationGroup"] as string;
		    }
		    set
		    {
				ViewState["ValidationGroup"] = value;
		    }
		}
		
		
		[Bindable(false),
		Category("JS"),
		DefaultValue("OnSignInJS"),
		Description("The Client JS to execute when user do sign in"),
		Localizable(false)]
		public string OnSignInJS
		{
		    get
		    {
		        return _OnSignInJS;
		    }
		    set
		    {
		        _OnSignInJS = value;
		    }
		}
		
		#endregion
		
		
		#region Inicializacion
		
		protected override void  CreateChildControls()
		{
			btnSignIn = new Button ();
			btnSignIn.ID = "btnSignIn";
			btnSignIn.Text = resSignIn.btnSignIn_Text;
			btnSignIn.ValidationGroup = ValidationGroup;
			btnSignIn.TabIndex = 3;
			btnSignIn.Click += btnSignIn_Click;

			btnSignUp = new Button ();
			btnSignUp.ID = "btnSignUp";
			btnSignUp.UseSubmitBehavior = false;
			btnSignUp.Text = resSignIn.btnSignUp_Text;
			btnSignUp.CausesValidation = false;
			btnSignUp.OnClientClick = 
				JS.GenerateGoToTop (LinkTarget, string.Format ("{0}/SignUp.aspx?ApplicationCode={1}", AuthenticationModule.SSOClientMainURL, frmApplicationCode)) +
				"HideOverByID ('div_esfssoSignInView');";
			btnSignUp.TabIndex = 4;

			lnkShow = new HyperLink ();
			lnkShow.ID = "lnkShow";
			lnkShow.Text = "Iniciar Sesión";
			lnkShow.CssClass = "lnkShowSignInView";
			lnkShow.ToolTip = "De click para diligenciar sus datos de usuario e iniciar sesión";
			lnkShow.Attributes ["onclick"] = "javascript:;esfsso_ShowSignInView ();";
			
			txtUserAlias = new TextBox ();
			txtUserAlias.ID = "txtUserAlias";
			txtUserAlias.CssClass = "txtUserAlias";
			txtUserAlias.MaxLength = 25;
			txtUserAlias.TabIndex = 1;
			
			txtUserPassword = new TextBox ();
			txtUserPassword.ID = "txtUserPassword";
			txtUserPassword.CssClass = "txtUserPassword";
			txtUserPassword.MaxLength = 25;
			txtUserPassword.TextMode = TextBoxMode.Password;
			txtUserPassword.TabIndex = 2;
			
			rfvTxtUserAlias = new RequiredFieldValidator ();
			rfvTxtUserAlias.ID = "rfvTxtUserAlias";
			rfvTxtUserAlias.ControlToValidate = txtUserAlias.ID;
			
			rfvTxtUserPassword = new RequiredFieldValidator ();
			rfvTxtUserPassword.ID = "rfvTxtUserPassword";
			rfvTxtUserPassword.ControlToValidate = txtUserPassword.ID;
			
			hidTopQueryString = new HiddenField ();
			hidTopQueryString.ID = "hidTopQueryString";

			lnkForgetPassword = new HyperLink ();
			lnkForgetPassword.ID = "lnkForgetPassword";
			lnkForgetPassword.CssClass = "RecoverLink";
			lnkForgetPassword.TabIndex = 5;
			lnkForgetPassword.ToolTip = resSignIn.lnkRecoverPassword_ToolTip;
			lnkForgetPassword.NavigateUrl = "#";
			lnkForgetPassword.Attributes ["onclick"] = JS.GenerateGoToTop (LinkTarget, string.Format ("{0}/RecoverPassword.aspx?ApplicationCode={1}", AuthenticationModule.SSOClientMainURL, frmApplicationCode)) +
				"HideOverByID ('div_esfssoSignInView');";
			lnkForgetPassword.Text = resSignIn.lnkRecoverPassword_Text;
			
			Controls.Add (lnkShow);

			Controls.Add (btnSignIn);
			
			Controls.Add (txtUserAlias);
			Controls.Add (txtUserPassword);
			
			Controls.Add (rfvTxtUserAlias);
			Controls.Add (rfvTxtUserPassword);
			
			Controls.Add (hidTopQueryString);
		}
		
		#endregion
		
		
		#region Eventos

		private void btnSignIn_Click(object sender, EventArgs pArgs)
		{
			_Presenter = new SignInPresenter (this);
			
			if (_Presenter.SignInByCredentials (WebConfigReader.GetSessionTimeoutMinutes ()))
			{
				AddSessionTimeoutScripts ();

				if (SignedIn != null)
				{
					SignedIn();
				}

				if (VerifyReturnURL ())
				{
					return;
				}
				else
				{
					JS.AddBeginJS(Page, 
						"HideOverByID ('div_esfssoSignInView'); " +
							JS.GenerateGoToTop (LinkTarget, ReadConfig.MainClientURL) +
							JS.GenerateWarning(string.Format("Su sesión acaba de iniciar, bienvenido(a):\n\n{0}\n\nEn un momento sera dirigido a la página principal.", AuthenticationModule.SignedInUser.calFullName)));
				}
			}
			else
			{
				JS.AddEndJS (Page, " esfsso_ShowSignInView ();");
			}
		}
		
		#endregion
		
		
		#region Funciones

		private void AddSessionTimeoutScripts ()
		{
			JS.AddEndJS (Page, "var sessionTimeoutMinutes = " + WebConfigReader.GetSessionTimeoutMinutes() + ";");

			JS.AddEndJS (Page, "var sessionStarted = true;");

			JS.AddEndJS (Page, 
				"var esfsso_CheckSessionTimeout_alerted = false; " +
				"var esfsso_CheckSessionTimeout_alertedend = false; " +
				"function esfsso_CheckSessionTimeout () { " + 
					"var sessionTimeoutMs = sessionTimeoutMinutes * 60 * 1000; " +
					"var dif = DateDiff (GetLastRequestDateTime (), new Date ()); " +
					"var dif = Math.max (dif, DateDiff (GetLastUserMovementDateTime (), new Date ())); " + 
					"if (!esfsso_CheckSessionTimeout_alertedend && dif >= sessionTimeoutMs) { esfsso_CheckSessionTimeout_alertedend = true; alert ('Su sesión ha caducado por inactividad!'); GoTop ('" + RequestHelper.AppendVarValueToHTTPURL (ReadConfig.MainURL, "D", "1", "CS", "true") + "'); }  " + 
					"else if (!esfsso_CheckSessionTimeout_alerted && dif >= (sessionTimeoutMs - 180000)) { esfsso_CheckSessionTimeout_alerted = true; alert ('Faltan menos de 3 minutos para que su sesión sea cerrada por inactividad'); } " + 
				"} " +
				"setInterval (esfsso_CheckSessionTimeout, 30000); ");
		}


		private bool VerifyReturnURL ()
		{
			string returnURL;
			
			
			if (hidTopQueryString != null && frmIsAuthenticated)
			{
				returnURL = HttpUtility.UrlDecode (RequestHelper.GetQueryStringValue (hidTopQueryString.Value, AuthenticationModule.RETURNURL));


				JS.AddEndJS (Page, OnSignInJS);
				
				if (!string.IsNullOrEmpty (returnURL))
				{
					JS.AddBeginJS (Page, "HideByID (DIVCOVERID); " + 
						JS.GenerateWarning (string.Format ("Su sesión acaba de iniciar.\n{0}\n\nEn un momento será enviado a la página solicitada", AuthenticationModule.SignedInUser.calFullName)) + 
						JS.GenerateGoToTop (LinkTarget, RequestHelper.AppendVarValueToHTTPURL (returnURL, AuthenticationModule.SESSIONID_NAME, AuthenticationModule.SessionID)));

					JS.ShowLoadingMessage(Page);

					return true;
				}
			}
			
			return false;
		}

		#endregion


		#region Render

		protected override void OnPreRender(EventArgs e)
		{
			Page.Trace.Write("SignIn PreRender Start");

			if (frmIsAuthenticated)
			{
				AddSessionTimeoutScripts(); 

				lnkShow.Visible = false;
			}
			else
			{
				lnkShow.Visible = true;
			}

			JS.AddEndJS (Page, " esfsso_ShowSignInView = function () { ShowOverByID ('div_esfssoSignInView'); $('#" + txtUserAlias.ClientID + "').focus (); }; ");

			Page.Trace.Write("SignIn PreRender End");
		}


		protected override void Render (HtmlTextWriter pWriter)
		{
			Page.Trace.Write ("SignIn Render Start");

			Page.Trace.Write(string.Format("lnkShow Visible {0} {1} {2} {3}", lnkShow.Text, lnkShow.Visible, frmUserAlias, frmIsAuthenticated));

			if (!lnkShow.Visible)
			{
				return;
			}

			lnkShow.RenderControl (pWriter);

				pWriter.AddAttribute (HtmlTextWriterAttribute.Class, CssClass + " divForm");
				pWriter.AddAttribute(HtmlTextWriterAttribute.Style, "display:none;");
				pWriter.AddAttribute(HtmlTextWriterAttribute.Id, "div_esfssoSignInView");
			pWriter.RenderBeginTag (HtmlTextWriterTag.Div);

			UserControlHelper.RenderFormHeader(pWriter, resSignIn.Title, resSignIn.SubTitle, true, "div_esfssoSignInView");

				// TODO: Traslates 
				UserControlHelper.RenderField (pWriter, txtUserAlias, resSignIn.User, null, rfvTxtUserAlias, ValidationGroup);
			
				UserControlHelper.RenderField (pWriter, txtUserPassword, resSignIn.Password, null, rfvTxtUserPassword, ValidationGroup);
				
				lnkForgetPassword.RenderControl (pWriter);
					
				UserControlHelper.StartRenderOperations (pWriter);
		
					btnSignIn.RenderControl (pWriter);
					btnSignUp.RenderControl (pWriter);
			
				pWriter.RenderEndTag ();
			
				hidTopQueryString.RenderControl (pWriter);

			pWriter.RenderEndTag ();


				pWriter.AddAttribute(HtmlTextWriterAttribute.Type, "text/javascript");
			pWriter.RenderBeginTag(HtmlTextWriterTag.Script);

			if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ReturnURL"]))
			{
				JS.AddEndJS (Page, "AddLoadEvent (function () { esfsso_ShowSignInView (); alert ('Diligencie sus credenciales para ingresar al recurso solicitado'); } ); ");
			}

			JS.AddEndJS (Page, "try { AddLoadEvent (new function () { try { document.getElementById ('" +
							hidTopQueryString.ClientID + "').value = top.location.search; } catch (ex) { alert ('El control de inicio de sesion no esta incluido apropiadamente'); } }); } catch (ex) {}");

			pWriter.RenderEndTag();

			Page.Trace.Write("SignIn Render End");
		}
		
		#endregion
		

		#region Miembros de ISignInViewer

		public string UserAlias
		{
			get { EnsureChildControls (); return txtUserAlias.Text; }
			set { txtUserAlias.Text = value; }
		}


		public string UserPassword
		{
			get { EnsureChildControls (); return txtUserPassword.Text; }
			set { txtUserPassword.Text = value; }
		}
		
		
		public User SignedInUser
		{
			set 
			{
				AuthenticationModule.SignedInUser = value;
			}
		}
		
		
		public bool SessionRemember { get { return false; } }

		#endregion
	}
}